package sparrowGui.utils
{
	import flash.utils.describeType;

	/**
	 * 工具包
	 * @author Pelephone
	 */
	public class SparrowUtil
	{
		/// 字符串处理 ///////////
		/**
		 * 转语言包对象字符串缓存对象
		 */
		private static var cacheLangObj:Object;

		/**
		 * 通过变量字符设置语言包
		 * 例如{aa}对{bb}说asdf,通过obj的aa,bb属性转成 A对B说asdf
		 */
		public static function langByObj(langStr:String,obj:Object):String
		{
			cacheLangObj = obj;
			var exp:RegExp = /{\w+}/g;
			var reStr:String = langStr.replace(exp, langToken);
			cacheLangObj = null;
			return reStr;
		}
		
		/**
		 * 解析字符
		 */
		private static function langToken(...args):String
		{
			var attr:String = args[0];
			attr = attr.substr(1,attr.length-2);
			var valStr:String = cacheLangObj.hasOwnProperty(attr)?String(cacheLangObj[attr]):"";
			return valStr;
		}
		
		/**
		 * 复制对象属性
		 * @param Jobj		要解析的Object对象
		 * @param voClz		要转成的vo对象的类名
		 */
		public static function copyObject(reObj:Object,vars:Object,ignoreProps:Array=null):*
		{
			var desc:XML = describeType( vars );
			// 设置 obj 的每个属性 prop
			for each(var prop:XML in desc.variable)
			{
				var propName:String = prop.@name;			// 变量名
				var propType:String = prop.@type;			// 变量类型
				
				// 忽略了
				if(ignoreProps && ignoreProps.indexOf(propName)>=0) continue;
				if(!reObj.hasOwnProperty(propName)) continue;
				
				reObj[propName] = vars[propName];
			}
			// 设置 obj 的每个属性 set/get
			for each(prop in desc.accessor)
			{
				propName = prop.@name;			// 变量名
				propType = prop.@type;			// 变量类型
				var access:String = prop.@access;
				
				// 忽略了
				if(ignoreProps && ignoreProps.indexOf(propName)>=0) continue;
				if(!reObj.hasOwnProperty(propName) || access=="readonly") continue;
				
				reObj[propName] = vars[propName];
			}
			// 如果是动态类就设置动态属性
			for (propName in vars)
			{
				if(ignoreProps && ignoreProps.indexOf(propName)>=0) continue;
				if(!reObj.hasOwnProperty(propName)) continue;
				reObj[propName] = vars[propName];
			}
			
			return reObj;
		}
		
		
		////////////////////////////////////////////////
		// xml解析部分
		///////////////////////////////////////////////
		
		/**
		 * 将xml上的属性信息解析到单个对象
		 * @param xml			要解析的xml
		 * @param obj	  		要将xml解析到对象类
		 * @param ignoreProps	忽略的属性名列表
		 * @return 
		 */		
		static public function parseXMLItem(xml:Object, obj:Object, ignoreProps:Array=null):*
		{
			if(xml) xml = xml[0];		// 调整到子结点
			if(xml==null || !XML(xml).length()) return;
			
			var desc:XMLList = describeType( obj )["variable"];
			// 设置 obj 的每个属性 prop
			for each(var prop:XML in desc)
			{
				var propName:String = prop.@name;			// 变量名
				var propType:String = prop.@type;			// 变量类型
				
				// 忽略了
				if(ignoreProps && ignoreProps.indexOf(propName)>=0) continue;
				
				var list:XMLList = xml.attribute(propName);
				// 先判断是否有此属性,没有再判断是否有些节点
				if(!list.length()) list = xml.child(propName);
				// 如果无节点或者节点是数组则不解析
				if(!list.length() || list.length()>1) continue;
				
				switch(propType)
				{
					// 基本类型
					case "Boolean":
						obj[propName] = Boolean(int(list))
						break;
					case "int":
					case "uint":
					case "String":
					case "Number":
					{
						obj[propName] = list;		// 变量名 和 xml节点名 必须相同 
					}
						break;
				}
			}
			return obj;
		}
		
		/**
		 * 解析xml并生成新的对象返回
		 * @param xml		  要解析的xml
		 * @param tClass	  要将xml解析生成的类
		 * @param ignoreProps 忽略的属性名列表
		 * @return 
		 */		
		static public function parseXMLByClass(xml:Object, tClass:Class, ignoreProps:Array=null):*
		{
			if(xml) xml = xml[0];		// 调整到子结点
			if(xml==null || !XML(xml).length()) return;
			var obj:Object = new (tClass)();
			parseXMLItem(xml,obj,ignoreProps);
			return obj;
		}
		
		/**
		 * 将xml解析到数组对象里面,不包括子节点
		 * @param xmlList
		 * @param defaultClass
		 * @param ignoreProps
		 * @return 
		 */		
		static public function parseXMLList(xmlList:XMLList, defaultClass:Class, ignoreProps:Array=null):Array
		{
			if(xmlList==null || defaultClass==null) return null;
			var arr:Array = new Array;
			for each(var xml:XML in xmlList)
			{
				var obj:Object = parseXMLByClass(xml, defaultClass, ignoreProps);
				arr.push( obj ); 
			}
			return arr;
		}
	}
}